package com.wuhao.lib_common.download;


import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;


import com.blankj.utilcode.util.ThreadUtils;
import com.liulishuo.okdownload.DownloadListener;
import com.liulishuo.okdownload.DownloadTask;
import com.liulishuo.okdownload.SpeedCalculator;
import com.liulishuo.okdownload.core.breakpoint.BlockInfo;
import com.liulishuo.okdownload.core.breakpoint.BreakpointInfo;
import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.cause.ResumeFailedCause;
import com.liulishuo.okdownload.core.listener.DownloadListener1;
import com.liulishuo.okdownload.core.listener.DownloadListener2;
import com.liulishuo.okdownload.core.listener.DownloadListener4WithSpeed;
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist;
import com.liulishuo.okdownload.core.listener.assist.Listener4SpeedAssistExtend;
import com.wuhao.lib_common.utils.LoggerHelper;
import com.wuhao.lib_common.utils.NotNullHelper;

import java.io.File;
import java.util.List;
import java.util.Map;

import io.reactivex.rxjava3.core.Observable;


/**
 * Created by zhangjianhao on 2018/8/21.
 * @author zhangjianhao
 */

public class OkDownloadeSingleHelper {
    private String url, parentPath, fileName;
    private SingleDownloadListener singleListener;
    private DownloadBean downloadBean;

    public OkDownloadeSingleHelper(String url, String parentPath, String fileName, SingleDownloadListener singleListener) {
        this.url = url;
        this.parentPath = parentPath;
        this.fileName = fileName;
        this.singleListener = singleListener;
    }

    public void startSingleTask() {
        ThreadUtils.getSinglePool().execute(new Runnable() {
            @Override
            public void run() {
                DownloadTask task = new DownloadTask.Builder(url, new File(parentPath))
                        .setFilename(fileName)
                        // the minimal interval millisecond for callback progress
                        .setMinIntervalMillisCallbackProcess(30)
                        // do re-download even if the task has already been completed in the past.
                        .setPassIfAlreadyCompleted(false)
                        .build();
                task.enqueue(listener4);
            }
        });

    }

    DownloadListener4WithSpeed listener4 = new DownloadListener4WithSpeed() {

        @Override
        public void infoReady(@NonNull DownloadTask task, @NonNull BreakpointInfo info, boolean fromBreakpoint, @NonNull Listener4SpeedAssistExtend.Listener4SpeedModel model) {
            if (singleListener != null) {
                downloadBean = new DownloadBean(0, info.getTotalLength());
                singleListener.connectedDownload(task, downloadBean);
            }
        }

        @Override
        public void progressBlock(@NonNull DownloadTask task, int blockIndex, long currentBlockOffset, @NonNull SpeedCalculator blockSpeed) {

        }

        @Override
        public void progress(@NonNull DownloadTask task, long currentOffset, @NonNull SpeedCalculator taskSpeed) {
            if (singleListener != null) {

                if (NotNullHelper.notEmpty(downloadBean)) {
                    downloadBean.setCurrentOffset(currentOffset);
                    downloadBean.setSpeed(taskSpeed.averageSpeed());
                    float v = (float) currentOffset / downloadBean.getTotalLength();
                    int progress = (int) Math.floor(v * 100);
                    downloadBean.setProgress(String.valueOf(progress) + "%");
                } else {
                    downloadBean = new DownloadBean(currentOffset, taskSpeed.averageSpeed());
                }
                singleListener.updateDownload(downloadBean);
            }
        }

        @Override
        public void blockEnd(@NonNull DownloadTask task, int blockIndex, BlockInfo info, @NonNull SpeedCalculator blockSpeed) {

        }

        @Override
        public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull SpeedCalculator taskSpeed) {
            try {
                LoggerHelper.e("updateAPK", cause + "");
                LoggerHelper.e("updateAPK", realCause.getMessage() + "");
            } catch (Exception e) {

            }
            if (singleListener != null) {
                if (cause.equals(EndCause.COMPLETED)) {
                    singleListener.stopDownload(true, task);
                } else {
                    singleListener.stopDownload(false, task);
                }
            }
        }

        @Override
        public void taskStart(@NonNull DownloadTask task) {
            if (singleListener != null) {
                singleListener.startDownload(task);
            }
        }

        @Override
        public void connectStart(@NonNull DownloadTask task, int blockIndex, @NonNull Map<String, List<String>> requestHeaderFields) {

        }

        @Override
        public void connectEnd(@NonNull DownloadTask task, int blockIndex, int responseCode, @NonNull Map<String, List<String>> responseHeaderFields) {
            Log.e("zjh","connectEnd");
        }
    };
    DownloadListener2 listener2 = new DownloadListener2() {
        @Override
        public void taskStart(@NonNull DownloadTask task) {

        }

        @Override
        public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause) {

        }
    };
    DownloadListener1 listener1 = new DownloadListener1() {
        @Override
        public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) {

            if (singleListener != null) {
                singleListener.startDownload(task);
            }
        }

        @Override
        public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) {
            if (singleListener != null) {
                singleListener.retryDownload(task);
            }

        }

        @Override
        public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) {
            if (singleListener != null) {
                downloadBean = new DownloadBean(currentOffset, totalLength);
                singleListener.connectedDownload(task, downloadBean);
            }

        }

        @Override
        public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) {
            if (singleListener != null) {
                downloadBean = new DownloadBean(currentOffset, totalLength);
                singleListener.updateDownload(downloadBean);
            }

        }

        @Override
        public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) {
            LoggerHelper.e("updateAPK", cause + "");
            if (singleListener != null) {
                if (cause.equals(EndCause.COMPLETED)) {
                    singleListener.stopDownload(true, task);
                } else {
                    singleListener.stopDownload(false, task);
                }

            }

        }
    };
    DownloadListener listener = new DownloadListener() {
        @Override
        public void taskStart(@NonNull DownloadTask task) {
        }

        @Override
        public void connectTrialStart(@NonNull DownloadTask task, @NonNull Map<String, List<String>> requestHeaderFields) {

        }

        @Override
        public void connectTrialEnd(@NonNull DownloadTask task, int responseCode, @NonNull Map<String, List<String>> responseHeaderFields) {

        }

        @Override
        public void downloadFromBeginning(@NonNull DownloadTask task, @NonNull BreakpointInfo info, @NonNull ResumeFailedCause cause) {

        }

        @Override
        public void downloadFromBreakpoint(@NonNull DownloadTask task, @NonNull BreakpointInfo info) {

        }

        @Override
        public void connectStart(@NonNull DownloadTask task, int blockIndex, @NonNull Map<String, List<String>> requestHeaderFields) {

        }

        @Override
        public void connectEnd(@NonNull DownloadTask task, int blockIndex, int responseCode, @NonNull Map<String, List<String>> responseHeaderFields) {

        }

        @Override
        public void fetchStart(@NonNull DownloadTask task, int blockIndex, long contentLength) {

        }

        @Override
        public void fetchProgress(@NonNull DownloadTask task, int blockIndex, long increaseBytes) {

        }

        @Override
        public void fetchEnd(@NonNull DownloadTask task, int blockIndex, long contentLength) {

        }

        @Override
        public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause) {

        }
    };

    public void setSingleListener(SingleDownloadListener singleListener) {
        this.singleListener = singleListener;
    }
}
